package clause

import "strings"

//Clause 保存构造一条sql需要的相关子句集合信息
//例如:
//select子句: select * from stu  参数:[]
//where子句: where name =?  参数:[dhy]
//...
type Clause struct {
	sql     map[Type]string
	sqlVars map[Type][]interface{}
}

//Type 当前sql子句的类型
type Type int

//目前只支持如下几种sql子句类型拼接
const (
	INSERT Type = iota
	VALUES
	SELECT
	LIMIT
	WHERE
	ORDERBY
)

//Set 设置一条子句信息到当前Clause内部
func (c *Clause) Set(name Type, vars ...interface{}) {
	if c.sql == nil {
		c.sql = make(map[Type]string)
		c.sqlVars = make(map[Type][]interface{})
	} else if c.sql[name] != "" {
		//避免多次进行构建造成额外开销
		return
	}
	sql, vars := generators[name](vars...)
	c.sql[name] = sql
	c.sqlVars[name] = vars
}

//Build 通过Clause内部的子句集合信息,和传入构建子句的顺序,最终构建出完整的sql子句和所需要的实际参数列表
func (c *Clause) Build(orders ...Type) (string, []interface{}) {
	var sqls []string
	var vars []interface{}
	for _, order := range orders {
		if sql, ok := c.sql[order]; ok {
			sqls = append(sqls, sql)
			vars = append(vars, c.sqlVars[order]...)
		}
	}
	return strings.Join(sqls, " "), vars
}
